﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;

namespace socketServer
{
    class Main
    {
        public int port = 7788;
        public string host = "127.0.0.1";

        //public Socket socket;
        public byte[] data = new byte[10240];
        public List<byte> list = new List<byte>();

        public byte[] sendData = null;

        public Main()
        {
            Start();
            Console.ReadKey();
        }

        public void Start()
        {
            IPAddress ip = IPAddress.Parse(host);
            IPEndPoint ipe = new IPEndPoint(ip, port);
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            serverSocket.Bind(ipe);
            serverSocket.Listen(99999);
            Console.WriteLine("监听已经打开，请等待");

            //开始异步连接   
            serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), serverSocket);

        }
        private void AcceptCallback(IAsyncResult result)
        {
            //上面将serverSocket本身传入回调方法中，现在要接收这个Socket。
            Socket serverSocket = result.AsyncState as Socket;
            //在接收到一台要连入的计算机后，我们要获得接入的计算机的信息，
            //就需要一个Socket专门用于和它通信。我们再声明一个clientSocket,
            //用于接收和发送接入方的数据
            Socket clientSocket = serverSocket.EndAccept(result);
            //在获得这个clientSocket后，使用BeginReceive方法来接收数据 
            clientSocket.BeginReceive(data, 0, data.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), clientSocket);
            //建立了通信，开启接收数据后，我们要循环接收其他要连接的计算机，所以这里接着进行等待接收，这样就实现了一个循环不断的接收
            serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), serverSocket);
            Console.WriteLine("连接已经建立");
            BeginSend(clientSocket);
        }
        private void ReceiveCallBack(IAsyncResult result)
        {
            //声明一个空的Socket
            Socket clientSocket = null;
            //当客户端被暴力关掉后，会造成服务器端的报警，这里将它try catch起来，防止程序崩溃
            try
            {
                //将传入的clientSocket进行接收，并且完成接收数据的操作
                clientSocket = result.AsyncState as Socket;
                int length = clientSocket.EndReceive(result);
                //for (int i = 0; i < length; i++)
                //{
                //    list.Add(data[i]);
                //}

                string message = Encoding.UTF8.GetString(data, 0, length);
                //string message = Encoding.UTF8.GetString(list.ToArray(), 0, list.co);

                //如果客户端正常关闭后，会向服务端发送长度为0的空数据，利用这一点将这个客户端关闭
                
                Console.WriteLine("收到消息：" + message);
                //clientSocket.Send(Encoding.UTF8.GetBytes("服务器发送的信息"));
                BeginSend(clientSocket);
                //重新调用开始接收数据
                clientSocket.BeginReceive(data, 0, data.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), clientSocket);
            }
            catch (SocketException e)
            {
                Console.WriteLine(e);
                if (clientSocket != null)
                {
                    clientSocket.Close();
                    clientSocket = null;
                }
            }
        }

        private void BeginSend(Socket clientSocket)
        {
            sendData = Encoding.UTF8.GetBytes("服务器发送的信息");
            clientSocket.BeginSend(sendData, 0, sendData.Length, SocketFlags.None, new AsyncCallback(SendCallBack), clientSocket);
        }

        private void SendCallBack(IAsyncResult result)
        {
            try
            {
                Socket clientSocket = (Socket)result.AsyncState;
                clientSocket.EndSend(result);
                Console.WriteLine("服务器发送结束");
            }
            catch (SocketException e)
            {
                Console.WriteLine(e);
            }
        }
    }
}
